using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using Jbe.TestSuite.TestDevices.Interface;
using Jbe.TestSuite.Infrastructure.Interface;
using System.Collections.ObjectModel;

namespace Jbe.TestSuite.TestDevices.Manager.Applications
{
    public class TestDeviceManager : ITestDeviceManager
    {
        private Dictionary<string, IControlViewFactory> factories;
        private ObservableCollection<IControlView> controlViews;
        private ReadOnlyObservableCollection<IControlView> readOnlyControlViews;


        public TestDeviceManager()
        {
            factories = new Dictionary<string, IControlViewFactory>();
            controlViews = new ObservableCollection<IControlView>();
            readOnlyControlViews = new ReadOnlyObservableCollection<IControlView>(controlViews);
        }


        public ReadOnlyObservableCollection<IControlView> ControlViews
        {
            get { return readOnlyControlViews; }
        }


        public void Register(IControlViewFactory factory)
        {
            if (factory == null) { throw new ArgumentNullException("factory"); }
            if (string.IsNullOrEmpty(factory.ProfileName)) { throw new ArgumentException("factory.ProfileName must not be null or empty."); }
            
            factories.Add(factory.ProfileName, factory);
        }

        public void Register(IDevice device)
        {
            if (device == null) { throw new ArgumentNullException("device"); }
            if (string.IsNullOrEmpty(device.ProfileName)) { throw new ArgumentException("device.ProfileName must not be null or empty."); }
            if (!factories.ContainsKey(device.ProfileName)) 
            { 
                throw new ArgumentException("No control view for the device profile '" + device.ProfileName + "' registered."); 
            }

            IControlView controlView = factories[device.ProfileName].Create(device);
            controlViews.Add(controlView);
        }

        public bool Deregister(IDevice device)
        {
            IControlView associatedControlView = controlViews.SingleOrDefault(cv => cv.Device == device);
            bool exists = associatedControlView != null;
            if (exists) { controlViews.Remove(associatedControlView); }
            return exists;
        }

        public void OpenDevice(IEnumerable<IControlView> controlViews)
        {
            foreach (IControlView controlView in controlViews)
            {
                controlView.Show();
            }
        }

        public void RemoveDevice(IEnumerable<IControlView> controlViews)
        {
            // We need to create a copy of controlViews because we modify the orignial list
            foreach (IControlView controlView in controlViews.ToList())
            {
                controlView.Close();
            }
        }
    }
}
